module controller.PlaylinkController;

import std.json : JSONValue, parseJSON;
import mir.ser.json : serializeJson;

import archttp.HttpRequest : HttpRequest;
import archttp.HttpResponse : HttpResponse;
import archttp.HttpStatusCode : HttpStatusCode;

import repository.PlaylinkRepo;
import utils.RespData;
import utils.Playlink : Playlink;
import utils.DataCache;
import utils.CacheKey : CacheKey;
import utils.SecurityVerification : signValidator;

class PlaylinkController
{
    PlaylinkRepo _playLinkRepo;
    this ()
    {
        _playLinkRepo = new PlaylinkRepo();
    }

    /** 
     * 解析视频播放地址
     */
    public void parsePlaylink (HttpRequest req, HttpResponse resp)
    {
        import std.algorithm : canFind, endsWith;
        import std.concurrency : scheduler, FiberScheduler;

        string[] vcates = ["teleplay", "movie", "animation"];

        JSONValue json = parseJSON(req.body());
        string vcate = json["vcate"].str;
        // string vid = json["vid"].str;
        string url = json["url"].str;
        string sign = json["sign"].str;
        // 判空
        if (vcate == "" || url == "")
        {
            resp.code(HttpStatusCode.BAD_REQUEST).json(RespData.newData(400, "错误的请求")).send();
            return;
        }
        if (!canFind(vcates, vcate))
        {
            resp.code(HttpStatusCode.BAD_REQUEST).json(RespData.newData(400, "错误的请求")).send();
            return;
        }

        import std.format : format;

        string reqParamsStr = format("%s%s", vcate, url);
        if (!signValidator(reqParamsStr, sign))
        {
            resp.code(HttpStatusCode.FORBIDDEN).json(RespData.newData(403, "签名不正确！")).send();
            return;
        }

        string vtable = vcate ~ "_vlinks";

        // 缓存中有数据直接取出返回
        auto data = cacheData.get(url);
        if (!data.isNull)
        {
            resp.json(RespData.newData(200, "ok", JSONValue(data.get))).send();
            return;
        }

        // 缓存中没有,则从数据库中查询是否有真实地址
        string realUrl = _playLinkRepo.getRealUrl(vtable, url);
        if (realUrl == "") // 数据库中没有
        {
            // 进行网络请求获取
            string realUrlFromNet = Playlink.getRealPlaylink(url);
            if (endsWith(realUrlFromNet, `.m3u8`))
            {
                // 接口1 https://video.isyour.love/player/getplayer?url=
                // 接口2 https://www.playm3u8.cn/jiexi.php?url=
                // 接口3 https://jx.2s0.cn/player/?url=
                // 接口4 https://jx.jsonplayer.com/player/?url=
                // 接口5 https://jx.aidouer.net/?url=
                // 接口6 https://jx.xmflv.com/?url=
                // 接口7 https://www.yemu.xyz/?url=
                // 接口8 https://jx.wujinkk.com/dplayer/?url=
                realUrl = "https://jx.wujinkk.com/dplayer/?url=" ~ realUrlFromNet;
            }
            else
            {
                realUrl = realUrlFromNet;
            }

            if (realUrl !is null && realUrl != "")
            {
                // 更新数据库，保存真实地址
                scheduler = new FiberScheduler();
                scheduler.start({
                    _playLinkRepo.updateLinkInfo(vtable, url, realUrl);
                });
            }
        }

        // 设置缓存
        cacheData.put(url, realUrl);

        resp.json(RespData.newData(200, "ok", JSONValue(realUrl))).send();
    }
}
